/*
 * @Author: 0x9DEFA478
 * @Date: 2022-01-23 15:31:56
 * @LastEditTime: 2022-03-06 19:52:54
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#ifndef __Console_H_NES_Console_H_
#define __Console_H_NES_Console_H_
#include "../H_NES.h"
#include "./H_NES_CPU.h"
#include "./H_NES_PPU.h"
#include "../Cartridge/H_NES_Cartridge.h"




#define vH_NES_CPU_NTSC_MCLKDiv                                   12
#define vH_NES_CPU_PAL_MCLKDiv                                    16
#define vH_NES_CPU_Dendy_MCLKDiv                                  15

#define vH_NES_PPU_NTSC_MCLKDiv                                   4
#define vH_NES_PPU_PAL_MCLKDiv                                    5
#define vH_NES_PPU_Dendy_MCLKDiv                                  5

#define vH_NES_Console_ProgressSize                               394




typedef struct{
  

  H_NES_CPU CPU;
  H_NES_Cartridge Cartridge;

  H_NES_PPU PPU;

  struct{
    Hint32 VblankNMI_Delay;//单位PPU周期的Vblank延迟
    Hint32 MMC4_CountDelay;//单位PPU周期的MMC4计数器触发计数延迟
  }CompatibilityOption;

  struct{
    Hbyte Controller1;
    Hbyte Controller2;
    Huint16 SrcStatus;
    Hbyte Reg_4016_W;
  }StandardController;

  struct{
    void* Command;
    void* Ack;
  }MessageQueue;

  H_NES_LL_Function LL_Function;


  Hsize TelevisionStandards;

  //内存管理函数集合
  struct{
    void* (*Malloc)(Husize);
    void (*Free)(void*);
  }Memory;

  int IsRun;
  int RetVal;
  

}H_NES_Console;

#define vH_NES_Message_FunctionIndex_Stop                         0
#define vH_NES_Message_FunctionIndex_GetProgress                  1
#define vH_NES_Message_FunctionIndex_LoadProgress                 2
#define vH_NES_Message_FunctionIndex_Start                        4
#define vH_NES_Message_FunctionIndex_SetVblankNMI_Delay           5
#define vH_NES_Message_FunctionIndex_SetMMC4_CountDelay           6

typedef struct{
  void* v;
  int FunctionIndex;
}H_NES_Message;




//============================================================================================================================================
//
// 主机方法
//
//============================================================================================================================================

//预退出调用
void H_NES_Console_PreExit(H_NES_Console* Console);

void H_NES_Console_Start(H_NES_Console* Console);

void H_NES_Console_GetProgress(H_NES_Console* Console,void* Progress);

void H_NES_Console_LoadProgress(H_NES_Console* Console,void* Progress);




//============================================================================================================================================
//
// Cartridge
//
//============================================================================================================================================

int H_NES_Cartridge_GetROM_Info(Hbyte* Header
  ,Huint32* PRG_ROM_Offset,Huint32* PRG_ROM_Size
  ,Huint32* CHR_ROM_Offset,Huint32* CHR_ROM_Size);
  
int H_NES_Cartridge_LoadROM_Scatter(H_NES_Console* Console,Hbyte* Header,Hbyte* PRG_ROM,Hbyte* CHR_ROM);

int H_NES_Cartridge_LoadROM(H_NES_Console* Console,void* NESROM);

void H_NES_Cartridge_UnloadROM(H_NES_Console* Console);




//============================================================================================================================================
//
// CPU方法
//
//============================================================================================================================================

void H_NES_CPU_Reset(H_NES_Console* Console);

void H_NES_CPU_Execute_NTSC(Hint32 MCLK,H_NES_Console* Console);

void H_NES_CPU_Execute_PAL(Hint32 MCLK,H_NES_Console* Console);

void H_NES_CPU_Execute_Dendy(Hint32 MCLK,H_NES_Console* Console);




//============================================================================================================================================
//
// APU方法
//
//============================================================================================================================================

Hbyte H_NES_APU_Read(Huint16 Address,H_NES_Console* Console);

void H_NES_APU_Write(Hbyte Value,Huint16 Address,H_NES_Console* Console);

void H_NES_APU_Reset(H_NES_Console* Console);

void H_NES_APU_Process(H_NES_Console* Console);




//============================================================================================================================================
//
// PPU方法
//
//============================================================================================================================================

void H_NES_PPU_Reset(H_NES_Console* Console);

void H_NES_PPU_RendrsFrame_NTSC(H_NES_Console* Console);

void H_NES_PPU_RendrsFrame_PAL(H_NES_Console* Console);

void H_NES_PPU_RendrsFrame_Dendy(H_NES_Console* Console);




//============================================================================================================================================
//
// IO方法
//
//============================================================================================================================================

Hbyte H_NES_IO_Read(Huint16 Address,H_NES_Console* Console);

void H_NES_IO_Write(Hbyte Value,Huint16 Address,H_NES_Console* Console);




#endif //__Console_H_NES_Console_H_
